package cn.anecansaitin.whimsy.common.enchantment;

import cn.anecansaitin.whimsy.Whimsy;
import cn.anecansaitin.whimsy.common.event.ArrowHitLivingEntityEvent;
import cn.anecansaitin.whimsy.common.register.ModEnchantments;
import net.minecraft.world.entity.EquipmentSlot;
import net.minecraft.world.entity.player.Player;
import net.minecraft.world.entity.projectile.AbstractArrow;
import net.minecraft.world.item.ArrowItem;
import net.minecraft.world.item.BowItem;
import net.minecraft.world.item.ItemStack;
import net.minecraft.world.item.Items;
import net.minecraft.world.item.enchantment.Enchantment;
import net.minecraft.world.item.enchantment.EnchantmentCategory;
import net.minecraft.world.item.enchantment.Enchantments;
import net.neoforged.bus.api.EventPriority;
import net.neoforged.bus.api.SubscribeEvent;
import net.neoforged.fml.common.Mod;
import net.neoforged.neoforge.event.entity.living.LivingGetProjectileEvent;
import net.neoforged.neoforge.event.entity.player.ArrowLooseEvent;

/**
 * 箭台，额外射出箭矢
 */
@Mod.EventBusSubscriber(modid = Whimsy.MODID)
public class ArrowRest extends Enchantment {
    public ArrowRest() {
        super(Rarity.RARE, EnchantmentCategory.BOW, new EquipmentSlot[]{EquipmentSlot.MAINHAND});
    }

    @Override
    public int getMaxLevel() {
        return 3;
    }

    @Override
    public boolean isTreasureOnly() {
        return true;
    }

    @Override
    public boolean isTradeable() {
        return false;
    }

    @Override
    public boolean isDiscoverable() {
        return false;
    }

    private static final ThreadLocal<ItemStack> PROJECTILE = ThreadLocal.withInitial(() -> ItemStack.EMPTY);

    @SubscribeEvent(priority = EventPriority.LOWEST)
    public static void onPrepareProjectile(LivingGetProjectileEvent event) {
        if (!(event.getEntity() instanceof Player)) {
            return;
        }

        if (event.getProjectileWeaponItemStack().getEnchantmentLevel(ModEnchantments.ARROW_REST.get()) < 1) {
            return;
        }

        PROJECTILE.set(event.getProjectileItemStack());
    }

    @SubscribeEvent
    public static void onFire(ArrowLooseEvent event) {
        if (event.getLevel().isClientSide()) {
            return;
        }

        ItemStack bow = event.getBow();

        if (!(bow.getItem() instanceof BowItem bowItem)) {
            return;
        }

        if (!event.hasAmmo()) {
            return;
        }

        ItemStack arrow = PROJECTILE.get();
        PROJECTILE.remove();
        int charge = event.getCharge();

        if (charge < 0) {
            return;
        }

        if (arrow.isEmpty()) {
            arrow = new ItemStack(Items.ARROW);
        }

        float velocity = BowItem.getPowerForTime(charge);

        if (velocity < 0.1) {
            return;
        }

        Player player = event.getEntity();
        ArrowItem arrowitem = (ArrowItem)(arrow.getItem() instanceof ArrowItem ? arrow.getItem() : Items.ARROW);
        int lvl = bow.getEnchantmentLevel(ModEnchantments.ARROW_REST.get());

        for (int i = 0; i < lvl; i++) {
            AbstractArrow abstractarrow = arrowitem.createArrow(event.getLevel(), arrow, player);
            abstractarrow = bowItem.customArrow(abstractarrow, bow);
            abstractarrow.addTag(Whimsy.MODID + "extra_arrow");

            int j = bow.getEnchantmentLevel(Enchantments.POWER_ARROWS);

            if (j > 0) {
                abstractarrow.setBaseDamage(abstractarrow.getBaseDamage() + (double)j * 0.5D + 0.5D);
            }

            int k = bow.getEnchantmentLevel(Enchantments.PUNCH_ARROWS);

            if (k > 0) {
                abstractarrow.setKnockback(k);
            }

            if (bow.getEnchantmentLevel(Enchantments.FLAMING_ARROWS) > 0) {
                abstractarrow.setSecondsOnFire(100);
            }

            float yRot = player.getYRot();
            abstractarrow.shootFromRotation(player, player.getXRot(), yRot, 0.0F, velocity * 3.0F, 1.0F);
            abstractarrow.pickup = AbstractArrow.Pickup.CREATIVE_ONLY;
            event.getLevel().addFreshEntity(abstractarrow);
        }
    }

    @SubscribeEvent
    public static void onHit(ArrowHitLivingEntityEvent event) {
        AbstractArrow arrow = event.getArrow();

        if (arrow.getTags().contains(Whimsy.MODID + "extra_arrow")) {
            event.getEntity().invulnerableTime = 9;
//            arrow.removeTag("extra_arrow"); //这个还不确定
        }
    }
}